package controller

import (
	"errors"
	"gitee.com/fierce_wolf/go-fox-edge-common/commEntity"
	"gitee.com/fierce_wolf/go-fox-edge-common/commEntityManager"
	"gitee.com/fierce_wolf/go-fox-edge-common/commRedisRpc"
	"gitee.com/fierce_wolf/go-fox-edge-common/commSql"
	"gitee.com/fierce_wolf/go-fox-edge-common/commUtil/Map"
	"gitee.com/fierce_wolf/go-fox-edge-common/commUtil/Method"
	"gitee.com/fierce_wolf/go-fox-edge-common/commUtil/Number"
	"gitee.com/fierce_wolf/go-fox-edge-common/commUtil/Pair"
	"gitee.com/fierce_wolf/go-fox-edge-common/commUtil/Uuid"
	"gitee.com/fierce_wolf/go-fox-edge-common/edgeEntity"
	"gitee.com/fierce_wolf/go-fox-edge-common/httpserver"
	"go-fox-edge-kernel-manager/utils/ExtendUtils"
	"go-fox-edge-kernel-manager/utils/PageUtils"
	"net/http"
	"time"
)

type deviceValueManageController struct {
}

func (e *deviceValueManageController) init() {
	httpserver.Server.POST("/device/value/page", e.selectEntityPage)

	httpserver.Server.POST("/device/value/remove", e.removeDeviceValueList)
}

func (e *deviceValueManageController) selectEntityPage(context httpserver.Context, body map[string]interface{}) (interface{}, error) {
	deviceName := Map.GetString(body, "deviceName", "")
	deviceType := Map.GetString(body, "deviceType", "")
	manufacturer := Map.GetString(body, "manufacturer", "")
	objectName := Map.GetString(body, "objectName", "")
	pageNum := Map.GetInt(body, "pageNum", 1)
	pageSize := Map.GetInt(body, "pageSize", 10)

	filter := ""
	if deviceName != "" {
		filter += " (device_name like '%" + deviceName + "%') AND"
	}
	if deviceType != "" {
		filter += " (device_type = '" + deviceType + "') AND"
	}
	if manufacturer != "" {
		filter += " (manufacturer = '" + manufacturer + "') AND"
	}
	if objectName != "" {
		filter += " (object_name = '" + objectName + "') AND"
	}
	if filter != "" {
		filter = filter[0 : len(filter)-len("AND")]
	}

	return e.selectEntityListPage(filter, "DESC", pageNum, pageSize)
}

func (e *deviceValueManageController) selectEntityListPage(filter string, order string, pageNum int, pageSize int) (interface{}, error) {
	// 从数据库的deviceObject中查询总数
	selectCount := PageUtils.MakeSelectCountSQL("tb_device_object", filter)

	total, err := commSql.QueryCount(selectCount)
	if err != nil {
		return nil, err
	}

	// 分页查询数据
	selectPage := PageUtils.MakeSelectSQLPage("tb_device_object", nil, nil, filter, order, pageNum, pageSize)
	entityList, err := commSql.Client.Query(edgeEntity.Type.DeviceObjectEntity.Type(), selectPage)
	if err != nil {
		return nil, err
	}

	// 从redis中直接读取真正的设备数值
	deviceNames := make([]string, 0)
	for _, deviceObjectEntity := range entityList {
		deviceValueEntity := edgeEntity.Type.DeviceValueEntity.Instance()
		deviceValueEntity.DeviceName = deviceObjectEntity.(*edgeEntity.DeviceObjectEntity).DeviceName

		deviceNames = append(deviceNames, deviceValueEntity.MakeServiceKey())
	}
	deviceValueMap, err := commEntityManager.GetEntityByServiceKeys(edgeEntity.Type.DeviceValueEntity.Type(), deviceNames)
	if err != nil {
		return nil, err
	}

	// 组织扩展信息：
	now := time.Now().UnixMilli()
	extendList := make([]map[string]interface{}, 0)
	for _, entity := range deviceValueMap {
		deviceValueEntity := entity.(*edgeEntity.DeviceValueEntity)

		for key, deviceObjectValue := range deviceValueEntity.Params {
			data := make(map[string]interface{})

			// 业务key
			data["deviceName"] = deviceValueEntity.DeviceName
			data["objectName"] = key
			data["objectTime"] = (now - deviceObjectValue.Time) / 1000
			data["objectValue"] = deviceObjectValue.Value
			data["updateTime"] = deviceObjectValue.Time

			extendList = append(extendList, data)
		}
	}

	mapList := commEntity.BuildMapList(entityList)

	// 增加扩展数据
	pairs := make([]*Pair.Pair, 0)
	extend := make([]string, 0)
	pairs = append(pairs, &Pair.Pair{Key: "deviceName", Value: "deviceName"})
	pairs = append(pairs, &Pair.Pair{Key: "objectName", Value: "objectName"})
	extend = append(extend, "objectValue")
	extend = append(extend, "objectTime")
	extend = append(extend, "updateTime")
	ExtendUtils.Extend(mapList, extendList, pairs, extend)

	data := make(map[string]interface{})
	data["list"] = mapList
	data["total"] = total

	return data, nil

}

func (e *deviceValueManageController) removeDeviceValueList(context httpserver.Context, body map[string]interface{}) (interface{}, error) {
	deviceValueList, _ := Map.GetValue(body, "objectNames")

	// 简单校验参数
	if Method.HasEmpty(deviceValueList) {
		return nil, errors.New("参数不能为空:objectNames")
	}

	// 删除设备的数值对象
	respondVO, err := e.deleteDeviceValue(deviceValueList.([]interface{}))
	if err != nil {
		return nil, err
	}

	if http.StatusOK != Number.MakeInt(respondVO.Code) {
		return respondVO.Data, nil
	} else {
		return nil, errors.New(respondVO.Msg)
	}
}

func (e *deviceValueManageController) deleteDeviceValue(deviceValueList []interface{}) (*commRedisRpc.RestFulRespondVO, error) {
	requestVO := commRedisRpc.Type.RestFulRequestVO.New()
	requestVO.Uuid = Uuid.RandomUUID()
	requestVO.Uri = "/manager/system/device/value/entities"
	requestVO.Method = "delete"
	requestVO.Data = deviceValueList

	// 发送数据
	err := commRedisRpc.Persist.Client.ManageRequest.Push(requestVO)
	if err != nil {
		return nil, err
	}

	// 等待消息的到达：根据动态key
	respond, err := commRedisRpc.Persist.Client.ManageRespond.Pop(requestVO.Uuid, 10*time.Second)
	if err != nil {
		return nil, err
	}
	if respond == nil {
		return nil, errors.New("服务响应超时")
	}

	return respond, nil
}
